package com.lifeverse.service;

import com.lifeverse.entity.LifeEntity;
import com.lifeverse.entity.enums.LifeEntityStatus;
import com.lifeverse.entity.enums.LifeEntityType;
import com.lifeverse.exception.BusinessException;
import com.lifeverse.factory.LifeEntityFactory;
import com.lifeverse.repository.LifeEntityRepository;
import com.lifeverse.util.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 生命体类型管理服务
 * 提供类型转换、升级、降级等功能
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class LifeEntityTypeService {
    
    private final LifeEntityRepository lifeEntityRepository;
    private final LifeEntityFactory lifeEntityFactory;
    
    /**
     * 转换生命体类型
     * 
     * @param entityId 生命体ID
     * @param targetType 目标类型
     * @param conversionConfiguration 转换配置
     * @return 转换后的生命体
     */
    @Transactional
    public LifeEntity convertType(Long entityId, LifeEntityType targetType, Map<String, Object> conversionConfiguration) {
        log.info("Converting life entity {} to type: {}", entityId, targetType);
        
        LifeEntity entity = lifeEntityRepository.findByIdAndDeletedFalse(entityId)
                .orElseThrow(() -> new BusinessException("生命体不存在: " + entityId));
        
        // 检查是否可以转换
        validateTypeConversion(entity, targetType);
        
        // 记录原始类型
        LifeEntityType originalType = entity.getType();
        
        // 设置转换状态
        entity.setStatus(LifeEntityStatus.EVOLVING);
        lifeEntityRepository.save(entity);
        
        try {
            // 执行类型转换
            performTypeConversion(entity, targetType, conversionConfiguration);
            
            // 记录转换历史
            recordTypeConversion(entity, originalType, targetType, conversionConfiguration);
            
            // 更新状态
            entity.setStatus(LifeEntityStatus.ACTIVE);
            entity.setLastEvolutionAt(LocalDateTime.now());
            entity.setEvolutionCount(entity.getEvolutionCount() + 1);
            
            LifeEntity savedEntity = lifeEntityRepository.save(entity);
            log.info("Successfully converted life entity {} from {} to {}", entityId, originalType, targetType);
            
            return savedEntity;
            
        } catch (Exception e) {
            log.error("Failed to convert life entity {} to type {}: {}", entityId, targetType, e.getMessage());
            // 恢复原始状态
            entity.setStatus(LifeEntityStatus.ACTIVE);
            lifeEntityRepository.save(entity);
            throw new BusinessException("类型转换失败: " + e.getMessage());
        }
    }
    
    /**
     * 升级生命体类型（向更复杂的类型转换）
     * 
     * @param entityId 生命体ID
     * @param upgradeConfiguration 升级配置
     * @return 升级后的生命体
     */
    @Transactional
    public LifeEntity upgradeType(Long entityId, Map<String, Object> upgradeConfiguration) {
        log.info("Upgrading life entity type: {}", entityId);
        
        LifeEntity entity = lifeEntityRepository.findByIdAndDeletedFalse(entityId)
                .orElseThrow(() -> new BusinessException("生命体不存在: " + entityId));
        
        LifeEntityType currentType = entity.getType();
        LifeEntityType targetType = determineUpgradeTarget(currentType, entity, upgradeConfiguration);
        
        if (targetType == currentType) {
            throw new BusinessException("当前类型已是最高级别，无法升级");
        }
        
        return convertType(entityId, targetType, upgradeConfiguration);
    }
    
    /**
     * 融合多个生命体创建混合类型
     * 
     * @param sourceEntityIds 源生命体ID列表
     * @param hybridName 混合生命体名称
     * @param hybridDescription 描述
     * @param fusionConfiguration 融合配置
     * @return 创建的混合生命体
     */
    @Transactional
    public LifeEntity fuseToHybrid(List<Long> sourceEntityIds, String hybridName, String hybridDescription, 
                                  Map<String, Object> fusionConfiguration) {
        log.info("Fusing {} entities to create hybrid: {}", sourceEntityIds.size(), hybridName);
        
        if (sourceEntityIds.size() < 2) {
            throw new BusinessException("融合至少需要2个生命体");
        }
        
        // 获取源生命体
        List<LifeEntity> sourceEntities = sourceEntityIds.stream()
                .map(id -> lifeEntityRepository.findByIdAndDeletedFalse(id)
                        .orElseThrow(() -> new BusinessException("生命体不存在: " + id)))
                .toList();
        
        // 验证融合条件
        validateFusionConditions(sourceEntities);
        
        // 设置源生命体状态
        sourceEntities.forEach(entity -> {
            entity.setStatus(LifeEntityStatus.MERGING);
            lifeEntityRepository.save(entity);
        });
        
        try {
            // 创建混合生命体
            LifeEntity hybridEntity = lifeEntityFactory.createHybridLifeEntity(
                    hybridName, hybridDescription, sourceEntities, fusionConfiguration);
            
            // 保存混合生命体
            LifeEntity savedHybrid = lifeEntityRepository.save(hybridEntity);
            
            // 记录融合历史
            recordFusionHistory(savedHybrid, sourceEntities, fusionConfiguration);
            
            // 更新源生命体状态（可选择是否保留）
            boolean preserveSourceEntities = (Boolean) fusionConfiguration.getOrDefault("preserveSourceEntities", false);
            if (!preserveSourceEntities) {
                sourceEntities.forEach(entity -> {
                    entity.setStatus(LifeEntityStatus.TERMINATED);
                    lifeEntityRepository.save(entity);
                });
            } else {
                sourceEntities.forEach(entity -> {
                    entity.setStatus(LifeEntityStatus.ACTIVE);
                    lifeEntityRepository.save(entity);
                });
            }
            
            log.info("Successfully created hybrid life entity: {}", hybridName);
            return savedHybrid;
            
        } catch (Exception e) {
            log.error("Failed to create hybrid life entity: {}", e.getMessage());
            // 恢复源生命体状态
            sourceEntities.forEach(entity -> {
                entity.setStatus(LifeEntityStatus.ACTIVE);
                lifeEntityRepository.save(entity);
            });
            throw new BusinessException("融合失败: " + e.getMessage());
        }
    }
    
    /**
     * 分裂混合生命体
     * 
     * @param hybridEntityId 混合生命体ID
     * @param splitConfiguration 分裂配置
     * @return 分裂后的生命体列表
     */
    @Transactional
    public List<LifeEntity> splitHybrid(Long hybridEntityId, Map<String, Object> splitConfiguration) {
        log.info("Splitting hybrid life entity: {}", hybridEntityId);
        
        LifeEntity hybridEntity = lifeEntityRepository.findByIdAndDeletedFalse(hybridEntityId)
                .orElseThrow(() -> new BusinessException("生命体不存在: " + hybridEntityId));
        
        if (hybridEntity.getType() != LifeEntityType.HYBRID) {
            throw new BusinessException("只有混合类型生命体可以分裂");
        }
        
        // 设置分裂状态
        hybridEntity.setStatus(LifeEntityStatus.SPLITTING);
        lifeEntityRepository.save(hybridEntity);
        
        try {
            // 执行分裂操作
            List<LifeEntity> splitEntities = performSplit(hybridEntity, splitConfiguration);
            
            // 保存分裂后的生命体
            List<LifeEntity> savedEntities = splitEntities.stream()
                    .map(lifeEntityRepository::save)
                    .toList();
            
            // 记录分裂历史
            recordSplitHistory(hybridEntity, savedEntities, splitConfiguration);
            
            // 更新原混合生命体状态
            boolean preserveHybrid = (Boolean) splitConfiguration.getOrDefault("preserveHybrid", false);
            if (!preserveHybrid) {
                hybridEntity.setStatus(LifeEntityStatus.TERMINATED);
            } else {
                hybridEntity.setStatus(LifeEntityStatus.ACTIVE);
            }
            lifeEntityRepository.save(hybridEntity);
            
            log.info("Successfully split hybrid life entity into {} entities", savedEntities.size());
            return savedEntities;
            
        } catch (Exception e) {
            log.error("Failed to split hybrid life entity: {}", e.getMessage());
            // 恢复状态
            hybridEntity.setStatus(LifeEntityStatus.ACTIVE);
            lifeEntityRepository.save(hybridEntity);
            throw new BusinessException("分裂失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取类型转换历史
     * 
     * @param entityId 生命体ID
     * @return 转换历史列表
     */
    public List<Map<String, Object>> getTypeConversionHistory(Long entityId) {
        LifeEntity entity = lifeEntityRepository.findByIdAndDeletedFalse(entityId)
                .orElseThrow(() -> new BusinessException("生命体不存在: " + entityId));
        
        try {
            Map<String, Object> metadata = JsonUtils.fromJson(entity.getMetadata(), Map.class);
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> history = (List<Map<String, Object>>) metadata.get("typeConversionHistory");
            return history != null ? history : List.of();
        } catch (Exception e) {
            log.warn("Failed to parse type conversion history for entity: {}", entityId);
            return List.of();
        }
    }
    
    /**
     * 检查类型兼容性
     * 
     * @param sourceType 源类型
     * @param targetType 目标类型
     * @return 是否兼容
     */
    public boolean checkTypeCompatibility(LifeEntityType sourceType, LifeEntityType targetType) {
        // 定义类型转换兼容性矩阵
        return switch (sourceType) {
            case INDIVIDUAL -> targetType == LifeEntityType.CORPORATE || targetType == LifeEntityType.CONCEPTUAL;
            case CORPORATE -> targetType == LifeEntityType.URBAN || targetType == LifeEntityType.HYBRID;
            case URBAN -> targetType == LifeEntityType.HYBRID || targetType == LifeEntityType.SYSTEM;
            case CONCEPTUAL -> targetType == LifeEntityType.HYBRID || targetType == LifeEntityType.SYSTEM;
            case SYSTEM -> targetType == LifeEntityType.HYBRID;
            case HYBRID -> false; // 混合类型不能直接转换，只能分裂
        };
    }
    
    /**
     * 验证类型转换
     */
    private void validateTypeConversion(LifeEntity entity, LifeEntityType targetType) {
        if (entity.getType() == targetType) {
            throw new BusinessException("目标类型与当前类型相同");
        }
        
        if (!checkTypeCompatibility(entity.getType(), targetType)) {
            throw new BusinessException("不支持从 " + entity.getType() + " 转换到 " + targetType);
        }
        
        if (!entity.isOperational()) {
            throw new BusinessException("生命体状态不允许类型转换");
        }
        
        // 检查能力要求
        if (!meetTypeRequirements(entity, targetType)) {
            throw new BusinessException("生命体能力不满足目标类型要求");
        }
    }
    
    /**
     * 检查是否满足类型要求
     */
    private boolean meetTypeRequirements(LifeEntity entity, LifeEntityType targetType) {
        return switch (targetType) {
            case CORPORATE -> entity.getWisdomScore().compareTo(BigDecimal.valueOf(50)) >= 0 &&
                           entity.getCollaborationScore().compareTo(BigDecimal.valueOf(60)) >= 0;
            case URBAN -> entity.getCollaborationScore().compareTo(BigDecimal.valueOf(70)) >= 0 &&
                        entity.getHealthScore().compareTo(BigDecimal.valueOf(60)) >= 0;
            case CONCEPTUAL -> entity.getCreativityScore().compareTo(BigDecimal.valueOf(70)) >= 0 &&
                             entity.getWisdomScore().compareTo(BigDecimal.valueOf(60)) >= 0;
            case HYBRID -> entity.getWisdomScore().compareTo(BigDecimal.valueOf(80)) >= 0 &&
                         entity.getCreativityScore().compareTo(BigDecimal.valueOf(70)) >= 0 &&
                         entity.getCollaborationScore().compareTo(BigDecimal.valueOf(80)) >= 0;
            case SYSTEM -> entity.getWisdomScore().compareTo(BigDecimal.valueOf(70)) >= 0 &&
                         entity.getHealthScore().compareTo(BigDecimal.valueOf(80)) >= 0;
            default -> true;
        };
    }
    
    /**
     * 执行类型转换
     */
    private void performTypeConversion(LifeEntity entity, LifeEntityType targetType, Map<String, Object> configuration) {
        // 保存原始属性
        Map<String, Object> originalAttributes = Map.of(
                "wisdom", entity.getWisdomScore(),
                "creativity", entity.getCreativityScore(),
                "collaboration", entity.getCollaborationScore(),
                "energy", entity.getEnergyLevel(),
                "health", entity.getHealthScore()
        );
        
        // 更新类型
        entity.setType(targetType);
        
        // 根据目标类型调整属性
        adjustAttributesForType(entity, targetType, configuration);
        
        // 更新配置
        updateConfigurationForType(entity, targetType, configuration);
    }
    
    /**
     * 根据类型调整属性
     */
    private void adjustAttributesForType(LifeEntity entity, LifeEntityType targetType, Map<String, Object> configuration) {
        double conversionEfficiency = (Double) configuration.getOrDefault("conversionEfficiency", 0.9);
        
        switch (targetType) {
            case CORPORATE -> {
                entity.setWisdomScore(entity.getWisdomScore().multiply(BigDecimal.valueOf(1.1 * conversionEfficiency)));
                entity.setCollaborationScore(entity.getCollaborationScore().multiply(BigDecimal.valueOf(1.05 * conversionEfficiency)));
            }
            case URBAN -> {
                entity.setCollaborationScore(entity.getCollaborationScore().multiply(BigDecimal.valueOf(1.2 * conversionEfficiency)));
                entity.setHealthScore(entity.getHealthScore().multiply(BigDecimal.valueOf(1.1 * conversionEfficiency)));
            }
            case CONCEPTUAL -> {
                entity.setCreativityScore(entity.getCreativityScore().multiply(BigDecimal.valueOf(1.3 * conversionEfficiency)));
                entity.setWisdomScore(entity.getWisdomScore().multiply(BigDecimal.valueOf(1.1 * conversionEfficiency)));
            }
            case HYBRID -> {
                entity.setWisdomScore(entity.getWisdomScore().multiply(BigDecimal.valueOf(1.2 * conversionEfficiency)));
                entity.setCreativityScore(entity.getCreativityScore().multiply(BigDecimal.valueOf(1.15 * conversionEfficiency)));
                entity.setCollaborationScore(entity.getCollaborationScore().multiply(BigDecimal.valueOf(1.25 * conversionEfficiency)));
            }
            case SYSTEM -> {
                entity.setWisdomScore(entity.getWisdomScore().multiply(BigDecimal.valueOf(1.15 * conversionEfficiency)));
                entity.setHealthScore(entity.getHealthScore().multiply(BigDecimal.valueOf(1.2 * conversionEfficiency)));
                entity.setEnergyLevel(entity.getEnergyLevel().multiply(BigDecimal.valueOf(1.1 * conversionEfficiency)));
            }
        }
    }
    
    /**
     * 更新类型配置
     */
    private void updateConfigurationForType(LifeEntity entity, LifeEntityType targetType, Map<String, Object> configuration) {
        Map<String, Object> newConfiguration = switch (targetType) {
            case CORPORATE -> Map.of("industry", "Technology", "employeeCount", 100, "revenue", 1000000.0);
            case URBAN -> Map.of("population", 500000L, "area", 100.0, "gdp", 5000000000.0);
            case CONCEPTUAL -> Map.of("conceptCategory", "Abstract", "abstractionLevel", 5, "complexityScore", 60.0);
            case HYBRID -> Map.of("fusionTypes", List.of(entity.getType().name()), "synergyLevel", 75.0);
            case SYSTEM -> Map.of("systemType", "Information", "systemComplexity", "Moderate", "processingCapacity", 1000.0);
            default -> Map.of();
        };
        
        // 合并用户配置
        if (configuration.containsKey("typeSpecificConfig")) {
            @SuppressWarnings("unchecked")
            Map<String, Object> userConfig = (Map<String, Object>) configuration.get("typeSpecificConfig");
            newConfiguration = Map.of(); // 这里应该合并配置，简化处理
        }
        
        entity.setConfiguration(JsonUtils.toJson(newConfiguration));
    }
    
    /**
     * 确定升级目标类型
     */
    private LifeEntityType determineUpgradeTarget(LifeEntityType currentType, LifeEntity entity, Map<String, Object> configuration) {
        // 根据当前类型和能力确定最佳升级目标
        return switch (currentType) {
            case INDIVIDUAL -> {
                if (entity.getCollaborationScore().compareTo(BigDecimal.valueOf(80)) >= 0) {
                    yield LifeEntityType.CORPORATE;
                } else if (entity.getCreativityScore().compareTo(BigDecimal.valueOf(80)) >= 0) {
                    yield LifeEntityType.CONCEPTUAL;
                } else {
                    yield LifeEntityType.CORPORATE; // 默认升级路径
                }
            }
            case CORPORATE -> LifeEntityType.HYBRID;
            case URBAN -> LifeEntityType.HYBRID;
            case CONCEPTUAL -> LifeEntityType.HYBRID;
            case SYSTEM -> LifeEntityType.HYBRID;
            case HYBRID -> currentType; // 已是最高级别
        };
    }
    
    /**
     * 验证融合条件
     */
    private void validateFusionConditions(List<LifeEntity> sourceEntities) {
        for (LifeEntity entity : sourceEntities) {
            if (!entity.isOperational()) {
                throw new BusinessException("生命体 " + entity.getName() + " 状态不允许融合");
            }
            if (entity.getHealthScore().compareTo(BigDecimal.valueOf(50)) < 0) {
                throw new BusinessException("生命体 " + entity.getName() + " 健康度过低，无法融合");
            }
        }
    }
    
    /**
     * 执行分裂操作
     */
    private List<LifeEntity> performSplit(LifeEntity hybridEntity, Map<String, Object> splitConfiguration) {
        // 从元数据中获取融合信息
        Map<String, Object> metadata = JsonUtils.fromJson(hybridEntity.getMetadata(), Map.class);
        @SuppressWarnings("unchecked")
        Map<String, Object> fusionInfo = (Map<String, Object>) metadata.get("fusion");
        
        if (fusionInfo == null) {
            throw new BusinessException("无法获取融合信息，无法执行分裂");
        }
        
        @SuppressWarnings("unchecked")
        List<String> sourceTypes = (List<String>) fusionInfo.get("sourceEntityTypes");
        
        // 创建分裂后的生命体
        return sourceTypes.stream()
                .map(typeStr -> {
                    LifeEntityType type = LifeEntityType.valueOf(typeStr);
                    String splitName = hybridEntity.getName() + "_Split_" + type.name();
                    return lifeEntityFactory.createLifeEntity(type, splitName, "分裂自: " + hybridEntity.getName(), Map.of());
                })
                .toList();
    }
    
    /**
     * 记录类型转换历史
     */
    private void recordTypeConversion(LifeEntity entity, LifeEntityType originalType, LifeEntityType targetType, 
                                    Map<String, Object> configuration) {
        try {
            Map<String, Object> metadata = JsonUtils.fromJson(entity.getMetadata(), Map.class);
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> history = (List<Map<String, Object>>) metadata.computeIfAbsent("typeConversionHistory", k -> new java.util.ArrayList<>());
            
            Map<String, Object> conversionRecord = Map.of(
                    "fromType", originalType.name(),
                    "toType", targetType.name(),
                    "conversionTime", LocalDateTime.now(),
                    "configuration", configuration
            );
            
            history.add(conversionRecord);
            entity.setMetadata(JsonUtils.toJson(metadata));
        } catch (Exception e) {
            log.warn("Failed to record type conversion history for entity: {}", entity.getId());
        }
    }
    
    /**
     * 记录融合历史
     */
    private void recordFusionHistory(LifeEntity hybridEntity, List<LifeEntity> sourceEntities, Map<String, Object> configuration) {
        // 融合历史已在工厂类中记录
    }
    
    /**
     * 记录分裂历史
     */
    private void recordSplitHistory(LifeEntity hybridEntity, List<LifeEntity> splitEntities, Map<String, Object> configuration) {
        try {
            Map<String, Object> metadata = JsonUtils.fromJson(hybridEntity.getMetadata(), Map.class);
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> history = (List<Map<String, Object>>) metadata.computeIfAbsent("splitHistory", k -> new java.util.ArrayList<>());
            
            Map<String, Object> splitRecord = Map.of(
                    "splitTime", LocalDateTime.now(),
                    "splitEntityIds", splitEntities.stream().map(LifeEntity::getId).toList(),
                    "configuration", configuration
            );
            
            history.add(splitRecord);
            hybridEntity.setMetadata(JsonUtils.toJson(metadata));
        } catch (Exception e) {
            log.warn("Failed to record split history for entity: {}", hybridEntity.getId());
        }
    }
}